# -*- coding: utf-8 -*-

###############################################################################
#
# Copyright (C) 2006 Maciej Wisniowski pigletto@gmail.com
#
# This module is part of RAMCacheManagerPlus and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
#
# Or, if you want this program may be distributed under the
# Zope Public License (ZPL) Version 2.1, as published on the Zope web site,
# http://www.zope.org/Resources/ZPL.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.
#
# See the LICENSE file for details.
#
###############################################################################
"""
    $Id: interfaces.py 8 2006-11-23 21:21:03Z pigletto $
"""

from zope.interface import implements
from zope.interface import Interface

class IRAMCacheMarker(Interface):
    """ Marker interface for RAMCache
    """


class IRAMCachePlus(Interface):
    """ RAMCachePlus is adapter for RAMCache that adds methods
        to allow flushing individual cache entries
    """

    def aggregateIndex(view_name, keywords_req, keywords_local):
        ''' Returns the index to be used when looking for or inserting
            a cache entry. Index is created from parameters but should
            return same value as original index from:
            RAMCacheManager.ObjectCacheEntries.aggregateIndex
            view_name is a string.
            keywords_req and keywords_local are dictionaries
        '''

    def invalidate(ob, view_name='', keywords_req={},
                   keywords_local={}, partial=0):
        """ Look at ICacheablePlus.invalidate docstring
        """


class ICacheableMarker(Interface):
    """ Marker interface for Cacheable
    """


class ICacheablePlus(Interface):
    """ The interface for CacheablePlus
    """

    def invalidate(view_name='', keywords_req={}, keywords_local={},
                   partial=0, REQUEST=None):
        """ Flushes cache entry that has index based on
            three params: view_name, keywords_req and keywords_local -
            this is default for RAMCacheManager.

            @view_name - view_name

            @keywords_req - dictionary that contains keys and values defined
                            as REQUEST_PARAMETERS for cache manager

            @keywords_local - additional keys that identify cache entry

            @partial - defines whether index built from parameters has to
                       be exactly the same as key in the cache

            Cache entry key is built with three parts:
              ('<view_name>', (<keywords_req>), (<keywords_local>) )

            When your'e adding entry to the cache you call:
                self.ZCacheable_set(res,
                                    view_name='myview',
                                    keywords=keyset)

            then:
                'view_name' is same as @view_name parameter of invalidate
                'keywords' is same as @keywords_local parameter of invalidate

                and by default RAMCacheManager adds one more thing to the
                cache key. It contains values from the REQUEST
                as defined in Properties tab of RAMCacheManager instance.

            Example 1 (caching your own function in Product):
                Say we have RAMCacheManager with REQUEST variables set to:
                ------------------------
                | AUTHENTICATED_USER    |
                | HTTP_X_FORWARDED_HOST |
                |                       |
                ------------------------

                then in the function that you want to cache you may use:

                 keyset = {'myidentkey':'myidentvalue'}
                 self.ZCacheable_set(someresult,
                                     view_name='myview',
                                     keywords=keyset)

                As a result of this there will be entry created
                in cache with the following values:

              ('myview',                                       # view_name
               (('AUTHENTICATED_USER', 'pigletto'),            # request keys
                ('HTTP_X_FORWARDED_HOST', '83.123.23.22') ),
               (('myidentkey', 'myidentkey'),                  # local keys
               )
              )

            To flush exactly this cache entry it is necessary to generate
            same cache key, so you have to call invalidate this way:

              view_name      = 'myview'
              keywords_req   = {'AUTHENTICATED_USER': 'pigletto',
                                'HTTP_X_FORWARDED_HOST', '83.123.23.22'}
              keywords_local = {'myidentkey':'myidentvalue'}

              ICacheablePlus(self).invalidate(view_name=view_name,
                                              keywords_req=keywords_req,
                                              keywords_local=keywords_local,
                                              partial = 0)

            If you want to flush entries associated with this function
            that match some criteria you may use partial = 1 like:

              keywords_req = {'AUTHENTICATED_USER': 'pigletto'}
              ICacheablePlus(self).invalidate(keywords_req=keywords_req,
                                              partial = 1)

            and this will flush all cache entries that are associated with
            user pigletto.

            Example 2 (index of the cache entry for cached Script (Python)):
              When you use Caching of objects via ZMI - with Cache tab,
              then it is easiest to use just keywords_req because you know
              them.

              Example cache key of Script (Python):

              ('',                                     # view_name
               (('AUTHENTICATED_USER', 'pigletto'),),   # request keys
               (('*', '()'),                           # local keys
                ('context', "('', 'sth')"),
                ('traverse_subpath', '[]')
               )
              )

            To flush this cache entry with @partial set to 0 it is
            necessary know all the params:
              view_name      = ''
              keywords_req   = {'AUTHENTICATED_USER': 'pigletto'}
              keywords_local = {'*':(),
                                'context': ('', 'sth'),
                                'traverse_subpath':[]
                               }
            with @partial set to 1 it is enough to use:
              keywords_req = {'AUTHENTICATED_USER': 'pigletto'}

            and this will flush all cache entries that contain this key.
        """
